package cn.com.visionsky.bocsz.bda.webservice.interceptor;

import java.io.*;
import java.sql.Timestamp;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.helpers.IOUtils;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.AbstractPhaseInterceptor;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.transport.http.AbstractHTTPDestination;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * Created by zhouqiufu on 2018/1/30.
 */
public class WebLogInInterceptor extends AbstractPhaseInterceptor<SoapMessage> {

    private static final Logger logger = LoggerFactory.getLogger(WebLogInInterceptor.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public WebLogInInterceptor() {
        super(Phase.RECEIVE);
    }

    public void handleMessage(SoapMessage msg) throws Fault {

        String serialNumber;
        String ip;
        String callTime;
        String callUrl;
        String callParam;
        String remark;

        HttpServletRequest httprequest = (HttpServletRequest)msg.get(AbstractHTTPDestination.HTTP_REQUEST);
        ip = httprequest.getRemoteAddr();
        callTime = new Timestamp(new Date().getTime()).toString();
        logger.info("客户端[ip]"+ip+" 访问时间[callTime]"+callTime);

        InputStream is = msg.getContent(InputStream.class);
        try{

            String content = "";
            if(is != null){
                content = IOUtils.toString(is);
                if(StringUtils.isNotBlank(content)){//回填，否则报错
                    String encoding = (String)msg.get(Message.ENCODING);
                    msg.setContent(InputStream.class, new ByteArrayInputStream(content.getBytes(encoding)));
                }
                is.close();
            }

            if(StringUtils.isNotBlank(content)){//获取参数和调用模块，调用模块的名称写在备注栏位
                content = format(content);
                serialNumber = getTagContent("uid", content);
                callUrl = msg.get(Message.REQUEST_URL).toString();
                callParam = content;
                remark = "[Request module（txnCode）]" + getTagContent("txnCode", content) + " [Message types（msgId）]" + getTagContent("msgId", content);
                logger.info("[API Remark]" + remark);
                insertAccessLog(serialNumber, ip, callTime, callUrl, callParam, remark);
            }
            
        }catch(Exception e){
            try {
                is.close();
            } catch (IOException ioe) {
                logger.info("[报文监控器]输入流关闭异常");
            }
            logger.info("报文监控器报错" + e);
        }finally {
            try {
                is.close();
            } catch (IOException e) {
                logger.info("[报文监控器]输入流关闭异常");
            }
        }

    }

    private String format(String content){
        content = content.replaceAll("&lt;","<");
        content = content.replaceAll("&gt;",">");
        return content;
    }

    private String getTagContent(String tag, String content){
        Pattern p = Pattern.compile("<" + tag + ">(.*)</" + tag + ">");
        Matcher m = p.matcher(content);
        while(m.find()){
            return m.group(1).trim();
        }
        return null;
    }

    private void insertAccessLog(String serialNumber, String ip, String callTime, String callUrl, String callParam, String remark){
        StringBuffer sql = new StringBuffer();
        sql.append(" insert into access_log (serial_number,ip,call_time,call_url,call_param,remark) values ( ");
        sql.append("'" + serialNumber + "' ,");
        sql.append("'" + ip + "' ,");
        sql.append("'" + callTime + "' ,");
        sql.append("'" + callUrl + "' ,");
        sql.append("'" + callParam + "' ,");
        sql.append("'" + remark + "' ");
        sql.append(" ) ");

        jdbcTemplate.execute(sql.toString());
    }

}
